{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:13.471160Z",
     "start_time": "2025-01-17T02:43:10.546185Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.0\n",
      "torch 2.5.1+cpu\n",
      "cpu\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 加载数据"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:14.579109Z",
     "start_time": "2025-01-17T02:43:13.471160Z"
    }
   },
   "source": [
    "from torchvision import datasets\n",
    "from torchvision.transforms import ToTensor\n",
    "\n",
    "# fashion_mnist图像分类数据集\n",
    "train_ds = datasets.FashionMNIST(\n",
    "    root=\"data\",\n",
    "    train=True,\n",
    "    download=True,\n",
    "    transform=ToTensor()\n",
    ")\n",
    "\n",
    "test_ds = datasets.FashionMNIST(\n",
    "    root=\"data\",\n",
    "    train=False,\n",
    "    download=True,\n",
    "    transform=ToTensor()\n",
    ")\n",
    "\n",
    "# torchvision 数据集里没有提供训练集和验证集的划分\n",
    "# 当然也可以用 torch.utils.data.Dataset 实现人为划分\n",
    "# 从数据集到dataloader\n",
    "train_loader = torch.utils.data.DataLoader(train_ds, batch_size=16, shuffle=True)\n",
    "val_loader = torch.utils.data.DataLoader(test_ds, batch_size=16, shuffle=False)"
   ],
   "outputs": [],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:14.582870Z",
     "start_time": "2025-01-17T02:43:14.579109Z"
    }
   },
   "source": [
    "from torchvision.transforms import Normalize\n",
    "\n",
    "# 遍历train_ds得到每张图片，计算每个通道的均值和方差\n",
    "def cal_mean_std(ds):\n",
    "    mean = 0.\n",
    "    std = 0.\n",
    "    for img, _ in ds:\n",
    "        mean += img.mean(dim=(1, 2))\n",
    "        std += img.std(dim=(1, 2))\n",
    "    mean /= len(ds)\n",
    "    std /= len(ds)\n",
    "    return mean, std\n",
    "\n",
    "\n",
    "# print(cal_mean_std(train_ds))\n",
    "# 0.2860， 0.3205\n",
    "transforms = nn.Sequential(\n",
    "    Normalize([0.2860], [0.3205])\n",
    ")\n"
   ],
   "outputs": [],
   "execution_count": 3
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型\n",
    "\n",
    "这里我们没有用`nn.Linear`的默认初始化，而是采用了xavier均匀分布去初始化全连接层的权重\n",
    "\n",
    "xavier初始化出自论文 《Understanding the difficulty of training deep feedforward neural networks》，适用于使用`tanh`和`sigmoid`激活函数的方法。当然，我们这里的模型采用的是`relu`激活函数，采用He初始化（何凯明初始化）会更加合适。感兴趣的同学可以自己动手修改并比对效果。\n",
    "\n",
    "|神经网络层数|初始化方式|early stop at epoch| val_loss | vla_acc|\n",
    "|-|-|-|-|-|\n",
    "|20|默认|\n",
    "|20|xaviier_uniform|\n",
    "|20|he_uniform|\n",
    "|...|\n",
    "\n",
    "He初始化出自论文 《Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification》"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:14.591557Z",
     "start_time": "2025-01-17T02:43:14.582870Z"
    }
   },
   "source": [
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, layers_num=2):\n",
    "        super().__init__()\n",
    "        self.transforms = transforms\n",
    "        self.flatten = nn.Flatten()\n",
    "        # 多加几层\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(28 * 28, 100),  # in_features=784, out_features=300\n",
    "            nn.ReLU(),\n",
    "            nn.AlphaDropout(p=0.2) # 增加dropout，p=0.2表示以0.2的概率将某些神经元置0，防止过拟合\n",
    "        )\n",
    "        # 加19层\n",
    "        for i in range(1, layers_num):\n",
    "            self.linear_relu_stack.add_module(f\"Linear_{i}\", nn.Linear(100, 100))\n",
    "            self.linear_relu_stack.add_module(f\"relu\", nn.ReLU())\n",
    "            nn.AlphaDropout(p=0.2) # 增加dropout\n",
    "        # 输出层\n",
    "        self.linear_relu_stack.add_module(\"Output Layer\", nn.Linear(100, 10))\n",
    "        \n",
    "        # 初始化权重\n",
    "        self.init_weights()\n",
    "        \n",
    "    def init_weights(self):\n",
    "        \"\"\"使用 xavier 均匀分布来初始化全连接层的权重 W\"\"\"\n",
    "        for m in self.modules():\n",
    "            if isinstance(m, nn.Linear):\n",
    "                nn.init.xavier_uniform_(m.weight)\n",
    "                nn.init.zeros_(m.bias)\n",
    "\n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 1, 28, 28]\n",
    "        x = self.transforms(x)\n",
    "        x = self.flatten(x)  \n",
    "        # 展平后 x.shape [batch size, 28 * 28]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 10]\n",
    "        return logits\n",
    "\n",
    "print(f\"{'layer_name':^40}\\tparamerters num\")\n",
    "for idx, (key, value) in enumerate(NeuralNetwork(20).named_parameters()):\n",
    "    print(\"{:<40}\\t{:^10}\".format(key, np.prod(value.shape)))"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               layer_name               \tparamerters num\n",
      "linear_relu_stack.0.weight              \t  78400   \n",
      "linear_relu_stack.0.bias                \t   100    \n",
      "linear_relu_stack.Linear_1.weight       \t  10000   \n",
      "linear_relu_stack.Linear_1.bias         \t   100    \n",
      "linear_relu_stack.Linear_2.weight       \t  10000   \n",
      "linear_relu_stack.Linear_2.bias         \t   100    \n",
      "linear_relu_stack.Linear_3.weight       \t  10000   \n",
      "linear_relu_stack.Linear_3.bias         \t   100    \n",
      "linear_relu_stack.Linear_4.weight       \t  10000   \n",
      "linear_relu_stack.Linear_4.bias         \t   100    \n",
      "linear_relu_stack.Linear_5.weight       \t  10000   \n",
      "linear_relu_stack.Linear_5.bias         \t   100    \n",
      "linear_relu_stack.Linear_6.weight       \t  10000   \n",
      "linear_relu_stack.Linear_6.bias         \t   100    \n",
      "linear_relu_stack.Linear_7.weight       \t  10000   \n",
      "linear_relu_stack.Linear_7.bias         \t   100    \n",
      "linear_relu_stack.Linear_8.weight       \t  10000   \n",
      "linear_relu_stack.Linear_8.bias         \t   100    \n",
      "linear_relu_stack.Linear_9.weight       \t  10000   \n",
      "linear_relu_stack.Linear_9.bias         \t   100    \n",
      "linear_relu_stack.Linear_10.weight      \t  10000   \n",
      "linear_relu_stack.Linear_10.bias        \t   100    \n",
      "linear_relu_stack.Linear_11.weight      \t  10000   \n",
      "linear_relu_stack.Linear_11.bias        \t   100    \n",
      "linear_relu_stack.Linear_12.weight      \t  10000   \n",
      "linear_relu_stack.Linear_12.bias        \t   100    \n",
      "linear_relu_stack.Linear_13.weight      \t  10000   \n",
      "linear_relu_stack.Linear_13.bias        \t   100    \n",
      "linear_relu_stack.Linear_14.weight      \t  10000   \n",
      "linear_relu_stack.Linear_14.bias        \t   100    \n",
      "linear_relu_stack.Linear_15.weight      \t  10000   \n",
      "linear_relu_stack.Linear_15.bias        \t   100    \n",
      "linear_relu_stack.Linear_16.weight      \t  10000   \n",
      "linear_relu_stack.Linear_16.bias        \t   100    \n",
      "linear_relu_stack.Linear_17.weight      \t  10000   \n",
      "linear_relu_stack.Linear_17.bias        \t   100    \n",
      "linear_relu_stack.Linear_18.weight      \t  10000   \n",
      "linear_relu_stack.Linear_18.bias        \t   100    \n",
      "linear_relu_stack.Linear_19.weight      \t  10000   \n",
      "linear_relu_stack.Linear_19.bias        \t   100    \n",
      "linear_relu_stack.Output Layer.weight   \t   1000   \n",
      "linear_relu_stack.Output Layer.bias     \t    10    \n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:14.626644Z",
     "start_time": "2025-01-17T02:43:14.592560Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    pred_list = []\n",
    "    label_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "        preds = logits.argmax(axis=-1)    # 验证集预测\n",
    "        pred_list.extend(preds.cpu().numpy().tolist())\n",
    "        label_list.extend(labels.cpu().numpy().tolist())\n",
    "        \n",
    "    acc = accuracy_score(label_list, pred_list)\n",
    "    return np.mean(loss_list), acc\n"
   ],
   "outputs": [],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:17.464410Z",
     "start_time": "2025-01-17T02:43:14.626644Z"
    }
   },
   "source": [
    "from torch.utils.tensorboard import SummaryWriter\n",
    "\n",
    "\n",
    "class TensorBoardCallback:\n",
    "    def __init__(self, log_dir, flush_secs=10):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            log_dir (str): dir to write log.\n",
    "            flush_secs (int, optional): write to dsk each flush_secs seconds. Defaults to 10.\n",
    "        \"\"\"\n",
    "        self.writer = SummaryWriter(log_dir=log_dir, flush_secs=flush_secs)\n",
    "\n",
    "    def draw_model(self, model, input_shape):\n",
    "        self.writer.add_graph(model, input_to_model=torch.randn(input_shape))\n",
    "        \n",
    "    def add_loss_scalars(self, step, loss, val_loss):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/loss\", \n",
    "            tag_scalar_dict={\"loss\": loss, \"val_loss\": val_loss},\n",
    "            global_step=step,\n",
    "            )\n",
    "        \n",
    "    def add_acc_scalars(self, step, acc, val_acc):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/accuracy\",\n",
    "            tag_scalar_dict={\"accuracy\": acc, \"val_accuracy\": val_acc},\n",
    "            global_step=step,\n",
    "        )\n",
    "        \n",
    "    def add_lr_scalars(self, step, learning_rate):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/learning_rate\",\n",
    "            tag_scalar_dict={\"learning_rate\": learning_rate},\n",
    "            global_step=step,\n",
    "            \n",
    "        )\n",
    "    \n",
    "    def __call__(self, step, **kwargs):\n",
    "        # add loss\n",
    "        loss = kwargs.pop(\"loss\", None)\n",
    "        val_loss = kwargs.pop(\"val_loss\", None)\n",
    "        if loss is not None and val_loss is not None:\n",
    "            self.add_loss_scalars(step, loss, val_loss)\n",
    "        # add acc\n",
    "        acc = kwargs.pop(\"acc\", None)\n",
    "        val_acc = kwargs.pop(\"val_acc\", None)\n",
    "        if acc is not None and val_acc is not None:\n",
    "            self.add_acc_scalars(step, acc, val_acc)\n",
    "        # add lr\n",
    "        learning_rate = kwargs.pop(\"lr\", None)\n",
    "        if learning_rate is not None:\n",
    "            self.add_lr_scalars(step, learning_rate)\n"
   ],
   "outputs": [],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:17.468381Z",
     "start_time": "2025-01-17T02:43:17.464410Z"
    }
   },
   "source": [
    "class SaveCheckpointsCallback:\n",
    "    def __init__(self, save_dir, save_step=5000, save_best_only=True):\n",
    "        \"\"\"\n",
    "        Save checkpoints each save_epoch epoch. \n",
    "        We save checkpoint by epoch in this implementation.\n",
    "        Usually, training scripts with pytorch evaluating model and save checkpoint by step.\n",
    "\n",
    "        Args:\n",
    "            save_dir (str): dir to save checkpoint\n",
    "            save_epoch (int, optional): the frequency to save checkpoint. Defaults to 1.\n",
    "            save_best_only (bool, optional): If True, only save the best model or save each model at every epoch.\n",
    "        \"\"\"\n",
    "        self.save_dir = save_dir\n",
    "        self.save_step = save_step\n",
    "        self.save_best_only = save_best_only\n",
    "        self.best_metrics = -1\n",
    "        \n",
    "        # mkdir\n",
    "        if not os.path.exists(self.save_dir):\n",
    "            os.mkdir(self.save_dir)\n",
    "        \n",
    "    def __call__(self, step, state_dict, metric=None):\n",
    "        if step % self.save_step > 0:\n",
    "            return\n",
    "        \n",
    "        if self.save_best_only:\n",
    "            assert metric is not None\n",
    "            if metric >= self.best_metrics:\n",
    "                # save checkpoints\n",
    "                torch.save(state_dict, os.path.join(self.save_dir, \"best.ckpt\"))\n",
    "                # update best metrics\n",
    "                self.best_metrics = metric\n",
    "        else:\n",
    "            torch.save(state_dict, os.path.join(self.save_dir, f\"{step}.ckpt\"))\n",
    "\n"
   ],
   "outputs": [],
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T02:43:17.472127Z",
     "start_time": "2025-01-17T02:43:17.468381Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "outputs": [],
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T03:03:39.075593Z",
     "start_time": "2025-01-17T02:43:17.473138Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=None,\n",
    "    save_ckpt_callback=None,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas)\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    "                preds = logits.argmax(axis=-1)\n",
    "            \n",
    "                acc = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())    \n",
    "                loss = loss.cpu().item()\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"acc\": acc, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss, val_acc = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"acc\": val_acc, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "                    \n",
    "                    # 1. 使用 tensorboard 可视化\n",
    "                    if tensorboard_callback is not None:\n",
    "                        tensorboard_callback(\n",
    "                            global_step, \n",
    "                            loss=loss, val_loss=val_loss,\n",
    "                            acc=acc, val_acc=val_acc,\n",
    "                            lr=optimizer.param_groups[0][\"lr\"],\n",
    "                            )\n",
    "                    \n",
    "                    # 2. 保存模型权重 save model checkpoint\n",
    "                    if save_ckpt_callback is not None:\n",
    "                        save_ckpt_callback(global_step, model.state_dict(), metric=val_acc)\n",
    "\n",
    "                    # 3. 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(val_acc)\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 100\n",
    "\n",
    "model = NeuralNetwork(layers_num=10)\n",
    "\n",
    "# 1. 定义损失函数 采用交叉熵损失\n",
    "loss_fct = nn.CrossEntropyLoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 1. tensorboard 可视化\n",
    "tensorboard_callback = TensorBoardCallback(\"runs/dropout\")\n",
    "tensorboard_callback.draw_model(model, [1, 28, 28])\n",
    "# 2. save best\n",
    "save_ckpt_callback = SaveCheckpointsCallback(\"checkpoints/dropout\", save_best_only=True)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=0.001)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=tensorboard_callback,\n",
    "    save_ckpt_callback=save_ckpt_callback,\n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/375000 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "a4231d7a5b8246dab29cdc9c9f4558e5"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 56 / global_step 210000\n"
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T03:03:39.241147Z",
     "start_time": "2025-01-17T03:03:39.075660Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    fig_num = len(train_df.columns)\n",
    "    fig, axs = plt.subplots(1, fig_num, figsize=(6 * fig_num, 5))\n",
    "    for idx, item in enumerate(train_df.columns):    \n",
    "        axs[idx].plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        axs[idx].plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        axs[idx].grid()\n",
    "        axs[idx].legend()\n",
    "        axs[idx].set_xlabel(\"step\")\n",
    "    \n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(record, sample_step=10000)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1200x500 with 2 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA9UAAAHACAYAAACszkseAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAtj5JREFUeJzs3QV4U/f6B/BvUvcWSgUoFHd3nyAbc3fmuxPune9uu/duY/tvTJkyd4UZMxjDxoDh7i5F2kJbqGvS//P+Tk5JPW3j+X6e5yxpmqanJxnJe175GcrLy8tBRERERERERA1mbPiPEBEREREREZFgUE1ERERERETUSAyqiYiIiIiIiBqJQTURERERERFRIzGoJiIiIiIiImokBtVEREREREREjcSgmoiIiIiIiKiRGFQTERERERERNZI/PIDZbMaxY8cQEREBg8Hg6t0hIiIfV15ejtzcXLRs2RJGI89P2wPf64mIyFPf7z0iqJY32aSkJFfvBhERUSWHDx9G69atXb0bXoHv9URE5Knv9x4RVMtZa/2PiYyMbNJjlZaWYt68eRg/fjwCAgLstIdUEx5r5+Lxdh4ea+dyx+Odk5OjAkD9/Ymaju/1novH23l4rJ2Lx9t5St30WNv6fu8RQbVeBiZvsvZ4ow0NDVWP405PmDfisXYuHm/n4bF2Lnc+3ixTth++13suHm/n4bF2Lh5v5yl182Nd3/s9G8GIiIiIiIiIGolBNREREREREVEjMagmIiIiIiIiaiSP6KkmIvK05RfKyspgMplcvSte02fl7++PoqIipx5TPz8/9XvZN01ERER1YVBNRGRHJSUlSE1NRUFBgat3xatOUiQkJKip0M4OcGVoSmJiIgIDA536e4mIiMhzMKgmIrITs9mMAwcOqAxny5YtVSDGLKd9jmteXh7Cw8NhNBqdFsjLCZITJ06o57RTp05O+91ERETkWRhUExHZiQRhEgDKeoaS4ST7kGMqxzY4ONipgW1ISIha1uPQoUMVv5+IiIioKp52JyKyM2Y0vQefSyIiIqoPPy0QERERERERNRKDaiIiIiIiIiJnBNXvvPMOevfujcjISLUNGzYMv//+e50/891336Fr166qF61Xr16YM2dOY/eViIg8QHJyMl577TW7PNbixYvV4Lfs7Gy7PB7ZZsmSJbjgggvUwD0ZtvfTTz/Z9Fz1798fQUFB6NixIz799FOn7CsREZFHBdWtW7fG888/j3Xr1mHt2rU466yzcNFFF2Hbtm013n/58uW45pprcOutt2LDhg24+OKL1bZ161Z77T8REdnBGWecgfvuu88uj7VmzRrccccddnksco38/Hz06dMH06dPt+n+MiH9vPPOw5lnnomNGzeq19Jtt92GP/74w+H7SkRE5GoNmv4tZ62tPfvssyp7vXLlSvTo0aPa/V9//XWcc845ePjhh9XXzzzzDObPn4+33noL7777blP3nYiInESWmDKZTPD3r/9to0WLFk7ZJ3Kcc889V222kvf0du3a4ZVXXlFfd+vWDcuWLcOrr76KCRMmOHBPiYiIPHhJLflwJaXdcjZbysBrsmLFCjzwwAOVbpM31/rKyIqLi9Wmy8nJUZelpaVqa7TcNPjNuApjcvNQOm5c4x+HbKI/V016zshmPN6uP9bytQSfsgSUbEK+Liw1uWQ/QwL8bFon++abb8Zff/2lNjkZKj766CNVZfTbb7/hiSeewJYtWzB37ly1XNiDDz6IVatWqX//JXiSE6xjx46teLz27dvj3nvvVZuQ8u333ntPtf/MmzcPrVq1wksvvYQLL7yw3n3Tj6PQj+0PP/yAp556Cnv37kViYiImT55c6b1GTvZK+fnhw4cRFRWFkSNHqvcr8f3336sTvPKzsuxZv379MGvWLISFhdX6++X3ynMrf4eO/59Vf7+3fg3o7/d1VT847L3eDf89LC414T8/b8fg5BhcObA1vI27HW9vxmNdv5X7s/D+0gN48oJuaNusactb8njXrdRkxlO/7kBiVDAmn9nBK4+1rfvT4KBaPlhJEF1UVITw8HD1YaR79+413jctLQ3x8fGVbpOv5fa6TJ06FVOmTKl2u3wYa8rar8GlJzHh+DZEwohf589v9ONQw0h1AjkPj7frjrVkcRMSEpCXl6fWNRaFJSYMm7bSJfu34oGhCAk8HQjW5umnn8aOHTvUv+WPPfaYum3nzp3q8t///rcKQqVPOjo6GkeOHFElvo8++qjqnZ0xY4ZqA1q9erUKuPVAVN4j9CBJyL/pskmA/v777+OGG27A5s2bERMTU+e+FRQUVFzPzc1VpcVXX321+v2XXHKJ+r0PPfSQem+49tprVauRBPOSOR08eDBOnTqlAj7ZF3nvue6669R+nH/++erx5HvSry0n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17t3bzz66KNYvnw5evbsqcrGdRJk33///Srwlr/hk08+scu+ETXUChtKv6v2VW87lu3w/SLyBk3t77V2hSUol15facFwlIy8YvxrxgbIilLFZWasPqCdePP23vWa+tiF9LF7K6PvDirznDNFRETOIJlpyVRLZljPUut9yj/++KPKUEsAfO2111abFN6U3ykBvZR4b926VQ1Lk6FpMphMpo0fOHAAjz/+uBpOJhO/JXDes2ePCsalBF16umU6uHxPgnEZdmbdc03kbv3UOk4AJ3Juf681WR6qQ4swFJWaVa+vI8jazPfP3Ij0nNMrDq20VLN4QitLU3vXa1yzev1Rr12z2veCan8tU21gppqIqBJZ1qpZs2aql1kCZ920adPUMDMpv5YycZnWrWexmyo0NBR//PGHmjYuS3VdfvnlaliaDCvTv79z504VdMswMllu65577sE//vEPNe07MzMTkyZNUtlq6bWWgWtTpkyxy74RNcTxnCI1jKe+fmpd98Qodbk7LQ+lJvucpCLyVvbo763e66v193637jAc4Z2/9mHpngwEBxjxr7M6qts8Zb3mnzcca3Lvel197N7IBweVsaeaiKgmUnJ97Fj1oWrJycmqX9maBLbWGlIOLn1x1qSkvOrj6yRbLVnynJwctQ617KMuMDBQlaoTuYOVB2zvpxatY0IQEeSP3OIy7DuRh64JWuaaiKpbtEPr702IDG5Sf6+1S/q1wkt/7MSagydVr29ybP1LUNpKAsdX5u1S15+5qCfGdGmBNxbtxY60HNVXHR1qiUfckLxH61UB9jiBYd3HLstrfbfuiFOGwzmb72Wq2VNNRERELiz9FrKMj760FoeVEdna39uqSf29VXt9R1l6fX+wY6+v6qP+RuujlqD0ioFJiIsIVuXmck7Z3fuqtx7VeteD7NC7XlMf++8O7mN3FZ8LqsvZU01E5DAy6Cw8PLzGrUePHq7ePSK3CaoFJ4AT2dbfu3i3pb/XTpnTar2+647YpddX76M+nluMTnHhePqi0+97+r8N7t5X/b2lHN4eveu19bHP2ZIKb+PD5d/ed4aEiMjVLrzwQgwZMqTG7wUE2O/NmciT+6l1HFZGZHt/b/82EpQ1vb/X2rju8YgM9ldrxsv0/hFNLEt+e/Fe1UcdEuCHt6/rj9BA/0pB9VerUty6p1h613/edMyupd9V+9hf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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-17T03:09:26.718583Z",
     "start_time": "2025-01-17T03:09:25.798787Z"
    }
   },
   "source": [
    "# dataload for evaluating\n",
    "#推理时alphadropout的p值是0，通过加dropout，一定程度解决了过拟合\n",
    "# load checkpoints\n",
    "model.load_state_dict(torch.load(\"checkpoints/dropout/best.ckpt\", weights_only=True,map_location=\"cpu\"))\n",
    "\n",
    "model.eval()\n",
    "loss, acc = evaluating(model, val_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\\naccuracy: {acc:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3412\n",
      "accuracy: 0.8863\n"
     ]
    }
   ],
   "execution_count": 12
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
